<template>
  <GoBack />
  <CenterBase>
    <template #CenterBase>
      <div class="header" style="margin-bottom: 28px">
        <span>我的收藏</span>
      </div>
      <a-list :data-source="dataSource">
        <template #loadMore>
          <div style="text-align: center; margin-top: 20px">
            <a-button type="primary" ghost @click="loadQusDes" :disabled="disableLoad">加载更多</a-button>
          </div>
        </template>
        <template #renderItem="{ item, index }">
          <a-list-item>
            <span>{{ item.time }}</span>
            <span style="float: left"><a @click="jumpTo(`/detail/${item.pid}`)">{{ item.content }}</a></span>
            <template #actions>
              <a-popconfirm title="确定删除吗？" ok-text="确定"  cancel-text="取消" @confirm="onDeleteCollect(item.id, index)">
                <a>删除</a>
              </a-popconfirm>
            </template>
          </a-list-item>
        </template>
      </a-list>
    </template>
  </CenterBase>
  <Footer />
</template>

<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { Button, List, message, Popconfirm } from 'ant-design-vue'
import { getQusDescription, getUserCollect, deleteCollect } from '@/service'
import { formatDate, subjectCode2Name } from '@/utils/check'
import {
  SESSION_NEW_COLLECT, USER_COLLECT, USER_COLLECT_DATA
} from '@/utils/constants'
import Footer from '@/components/Footer.vue'
import CenterBase from '@/components/CenterBase.vue'
import GoBack from '@/components/GoBack.vue'
import {
  setCache, getCache, delCache
} from '@/utils/common'

interface CollectionItem {
  id: number,
  pid: number,
  time: string,
  content: string
}
interface CollectionItem2 {
  id: number,
  pid: number,
  time: string
}

interface QusDes {
  id: number,
  year: string,
  number: number,
  tag: string,
  subject: string,
  type: string
}

export default defineComponent({
  name: 'MyCollection',
  components: {
    Footer,
    CenterBase,
    AList: List,
    AListItem: List.Item,
    AButton: Button,
    APopconfirm: Popconfirm,
    GoBack
  },
  setup () {
    const router = useRouter()
    const dataSource = ref<CollectionItem[]>([])
    const loadCursor = ref<number>(0)
    const disableLoad = ref<boolean>(false)
    const collectIds = ref<CollectionItem2[]>([])
    const initFlag = ref<boolean>(true)

    const restoreDataSource = ():boolean => {
      if (initFlag.value) {
        const cached = getCache(USER_COLLECT_DATA)
        if (cached.length > 0) {
          initFlag.value = false
          const data = JSON.parse(cached)
          loadCursor.value = data.cursor
          dataSource.value = data.data
          return true
        }
      }
      return false
    }

    const loadSessionNewCollection = ():boolean => {
      const cache = getCache(SESSION_NEW_COLLECT)
      if (cache.length > 0) {
        const d = JSON.parse(cache)
        const reqIds:number[] = []
        const idxMap:Map<number, number> = new Map<number, number>()
        d.forEach((v: CollectionItem2, idx: number) => {
          reqIds.push(v.pid)
          idxMap.set(v.pid, idx)
        })
        getQusDescription(reqIds)
          .then((response) => {
            if (response.status !== 200) {
              return
            }
            const resp = response.data
            if (resp.code !== 0 || resp.data === null) {
              return
            }
            resp.data.forEach((v:QusDes) => {
              const j = idxMap.get(v.id)
              if (j !== undefined) {
                const t = d[j].time
                const cid = d[j].id
                const c = buildColDes(v, cid, t)
                dataSource.value.unshift(c)
              }
            })
            const cached = {
              cursor: loadCursor.value,
              data: dataSource.value
            }
            setCache(USER_COLLECT_DATA, JSON.stringify(cached))
            delCache(SESSION_NEW_COLLECT)
          })
        return true
      }
      return false
    }

    const buildColDes = (e: QusDes, cid: number, time: string): CollectionItem => {
      const sub = subjectCode2Name(e.subject)
      const tag = e.tag
      const type = e.type
      const year = e.year
      const number = e.number
      const tags = tag.split('#')
      const showTag = tags.slice(0, 1)
      let content = ''
      if (type === '0') {
        content = `其他 ${sub} ${showTag.join(',')}`
      } else {
        content = `${type} ${sub} ${year}年第${number}题 ${showTag.join(',')}`
      }
      return {
        id: cid,
        pid: e.id,
        time: formatDate(new Date(time)),
        content: content
      }
    }

    const loadQusDes = () => {
      const flag = restoreDataSource()
      loadSessionNewCollection()
      if (flag) {
        return
      }
      const batchSize = 5
      const len = collectIds.value.length
      const start = loadCursor.value
      if (start >= len) {
        message.info('已经加载全部收藏')
        disableLoad.value = true
        return
      }
      const end = Math.min(start + batchSize, len)
      const ids:number[] = []
      const idxMap:Map<number, number> = new Map<number, number>()
      for (let i = start; i < end; i++) {
        const pid = collectIds.value[i].pid
        ids.push(pid)
        idxMap.set(pid, i)
      }
      if (ids.length < 1) {
        return
      }
      getQusDescription(ids)
        .then(response => {
          if (response.status !== 200) {
            message.warn('请求出错')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.warn('返回出错')
            return
          }
          loadCursor.value = end
          const data = resp.data
          // id, year, number, tag, subject, type
          data.forEach((e: QusDes) => {
            const pid = e.id
            const j = idxMap.get(pid)
            if (j === undefined) {
              return
            }
            const cid = collectIds.value[j].id
            const t = collectIds.value[j].time
            dataSource.value.push(buildColDes(e, cid, t))
          })
          const cached = {
            cursor: loadCursor.value,
            data: dataSource.value
          }
          setCache(USER_COLLECT_DATA, JSON.stringify(cached))
        })
    }

    const loadCollection = () => {
      const cached = getCache(USER_COLLECT)
      if (cached.length > 0) {
        collectIds.value = JSON.parse(cached)
        loadQusDes()
        return
      }
      getUserCollect()
        .then((response) => {
          if (response.status !== 200) {
            message.warn('请求出错')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.warn('返回出错')
            return
          }
          resp.data.forEach((v: any) => {
            collectIds.value.push({
              id: v.id,
              pid: v.pid,
              time: v.created
            })
          })
          setCache(USER_COLLECT, JSON.stringify(collectIds.value))
          loadQusDes()
        })
    }

    const onDeleteCollect = (id: number, idx: number) => {
      const d = dataSource.value
      deleteCollect(id)
        .then((response) => {
          if (response.status !== 200) {
            return
          }
          const resp = response.data
          if (resp.code === 0 && resp.data === true) {
            d.splice(idx, 1)
            const cached = {
              cursor: loadCursor.value,
              data: dataSource.value
            }
            sessionStorage.setItem(USER_COLLECT_DATA, JSON.stringify(cached))
          }
        })
    }

    const jumpTo = (url: string) => {
      router.push(url)
    }

    onMounted(() => {
      loadCollection()
    })
    return {
      dataSource,
      disableLoad,
      loadQusDes,
      jumpTo,
      onDeleteCollect
    }
  }
})
</script>

<style scoped>
.header {
  text-align: center;
  margin-top: 26px;
  background-color: #1abc9c;
  border-radius: 10px;
  padding: 12px 0;
}
.header span {
  font-size: 2em;
  color: white;
  display: inline-block;
}
</style>
